from flask import Flask, render_template, request, jsonify, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_cors import CORS
from datetime import datetime
import os
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

app = Flask(__name__)

# 数据库配置 - 支持SQLite和MySQL
default_db = 'sqlite:///clipboard.db'  # 腾讯云一键部署默认使用SQLite
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', default_db)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-secret-key-here')

# 初始化扩展
db = SQLAlchemy(app)
migrate = Migrate(app, db)

# 增强CORS配置，支持腾讯云部署
CORS(app, resources={
    r"/api/*": {
        "origins": ["*"],  # 允许所有来源
        "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
        "allow_headers": ["Content-Type", "Authorization"]
    }
})

# 定义模型
class Collection(db.Model):
    """收藏模型"""
    __tablename__ = 'collections'
    
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text)
    url = db.Column(db.String(500))
    source = db.Column(db.String(100))  # 来源平台
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系
    category = db.relationship('Category', backref='collections')
    tags = db.relationship('Tag', secondary='collection_tags', backref='collections')
    
    def to_dict(self):
        return {
            'id': self.id,
            'title': self.title,
            'content': self.content,
            'url': self.url,
            'source': self.source,
            'category_id': self.category_id,
            'category_name': self.category.name if self.category else None,
            'tags': [tag.name for tag in self.tags],
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

class Category(db.Model):
    """分类模型"""
    __tablename__ = 'categories'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, unique=True)
    description = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'created_at': self.created_at.isoformat()
        }

class Tag(db.Model):
    """标签模型"""
    __tablename__ = 'tags'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False, unique=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'created_at': self.created_at.isoformat()
        }

# 多对多关系表
collection_tags = db.Table('collection_tags',
    db.Column('collection_id', db.Integer, db.ForeignKey('collections.id'), primary_key=True),
    db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'), primary_key=True)
)

def _resolve_tags(tag_names):
    """根据标签名列表返回Tag实体列表（不存在则创建）。"""
    if not tag_names:
        return []
    resolved = []
    for name in tag_names:
        if not name:
            continue
        tag = Tag.query.filter_by(name=name).first()
        if not tag:
            tag = Tag(name=name)
            db.session.add(tag)
        resolved.append(tag)
    return resolved

@app.route('/')
def index():
    """主页"""
    return render_template('index.html')

@app.route('/api/collections', methods=['GET'])
def get_collections():
    """获取所有收藏"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        search = request.args.get('search', '')
        category_id = request.args.get('category_id', type=int)
        
        query = Collection.query
        
        if search:
            query = query.filter(Collection.title.contains(search) | Collection.content.contains(search))
        
        if category_id:
            query = query.filter(Collection.category_id == category_id)
        
        collections = query.paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return jsonify({
            'collections': [collection.to_dict() for collection in collections.items],
            'total': collections.total,
            'pages': collections.pages,
            'current_page': page
        })
    except Exception as e:
        app.logger.error(f"获取收藏失败: {str(e)}")
        return jsonify({'error': '获取收藏失败', 'message': str(e)}), 500

@app.route('/api/collections', methods=['POST'])
def create_collection():
    """创建新收藏"""
    data = request.get_json()
    category_id = data.get('category_id') or None
    tag_names = data.get('tags', [])
    tags = _resolve_tags(tag_names)

    collection = Collection(
        title=data.get('title'),
        content=data.get('content'),
        url=data.get('url'),
        source=data.get('source'),
        category_id=category_id
    )

    db.session.add(collection)
    if tags:
        collection.tags = tags
    db.session.commit()
    
    return jsonify(collection.to_dict()), 201

@app.route('/api/collections/<int:collection_id>', methods=['GET'])
def get_collection(collection_id):
    """获取单个收藏"""
    collection = Collection.query.get_or_404(collection_id)
    return jsonify(collection.to_dict())

@app.route('/api/collections/<int:collection_id>', methods=['PUT'])
def update_collection(collection_id):
    """更新收藏"""
    collection = Collection.query.get_or_404(collection_id)
    data = request.get_json()
    
    collection.title = data.get('title', collection.title)
    collection.content = data.get('content', collection.content)
    collection.url = data.get('url', collection.url)
    collection.source = data.get('source', collection.source)
    collection.category_id = data.get('category_id') or collection.category_id
    if 'tags' in data:
        collection.tags = _resolve_tags(data.get('tags') or [])
    collection.updated_at = datetime.utcnow()
    
    db.session.commit()
    return jsonify(collection.to_dict())

@app.route('/api/collections/<int:collection_id>', methods=['DELETE'])
def delete_collection(collection_id):
    """删除收藏"""
    collection = Collection.query.get_or_404(collection_id)
    db.session.delete(collection)
    db.session.commit()
    return '', 204

@app.route('/api/categories', methods=['GET'])
def get_categories():
    """获取所有分类"""
    categories = Category.query.all()
    # 如果没有分类，自动创建默认分类
    if not categories:
        default_categories = [
            {'name': '技术', 'description': '技术相关文章和资源'},
            {'name': '生活', 'description': '生活感悟和日常分享'},
            {'name': '学习', 'description': '学习笔记和教程'},
            {'name': '工作', 'description': '工作相关内容和经验'},
            {'name': '娱乐', 'description': '娱乐内容和有趣的东西'}
        ]
        for cat in default_categories:
            db.session.add(Category(name=cat['name'], description=cat['description']))
        db.session.commit()
        categories = Category.query.all()
    return jsonify([category.to_dict() for category in categories])

@app.route('/api/categories', methods=['POST'])
def create_category():
    """创建新分类"""
    data = request.get_json()
    category = Category(name=data.get('name'), description=data.get('description'))
    db.session.add(category)
    db.session.commit()
    return jsonify(category.to_dict()), 201

@app.route('/api/tags', methods=['GET'])
def get_tags():
    """获取所有标签"""
    tags = Tag.query.all()
    return jsonify([tag.to_dict() for tag in tags])

@app.route('/api/tags', methods=['POST'])
def create_tag():
    """创建新标签"""
    data = request.get_json()
    tag = Tag(name=data.get('name'))
    db.session.add(tag)
    db.session.commit()
    return jsonify(tag.to_dict()), 201

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    
    # 支持环境变量配置端口
    port = int(os.getenv('PORT', 5000))
    host = os.getenv('HOST', '0.0.0.0')
    debug = os.getenv('FLASK_ENV', 'development') == 'development'
    
    app.run(debug=debug, host=host, port=port)
